<template>

	<view>
		<canvas :style="'position:absolute;top:-9999px;background:#000;width: ' + width + 'px; height: ' + height + 'px;'" id="offcanvas" canvas-id="offcanvas" @touchstart="touchstart"></canvas>
		<canvas disable-scroll="true" :style="'background:#000;width: ' + width + 'px; height: ' + height + 'px;'" id="canvas" canvas-id="canvas" @touchstart="touchstart"></canvas>
		<!-- <button style="position: absolute;bottom:0;left:0;" @click="joke">dddddddddd</button> -->
	</view>
</template>
<script>
	let context;
	var c1, c2, c3;
	export default{
		name: "wormjan-jigsaw",
		data(){
			return {
				win:false,
				width:0,
				height:0,
				status:0,
				sq1:{x: 0, y: 0, r:2, speed: 2, vx: 0, vy: 0},
				btn_choose_img:{x: 0, y: 0, text_x: 0, text_y: 0, width: 0, height: 0, text: '拍照或选择图片'},
				image:'',
				ppline:3,
				space:1,	//间隙
				force_width:0,
				img_width:0,
				img_height:0,
				steps:0,
				first_side:0,
				white_index:0,
				img_obj:function(opos, nowpos, img, x, y, width, height){
					this.opos = opos;
					this.nowpos = nowpos;
					this.img = img;
					this.nowx = x;
					this.nowy = y;
					this.is_white = false;
					this.width = width;
					this.height = height;
				},
				Dot: function (x, y, r, color) {
					const that = this;
					this.dx = x;
					this.dy = y;
					this.r = r;
					this.color = color;
					this.hue = 120;
					//this.hue_final = parseInt(Math.random() * (140 - 100 + 1) + 100, 10)
					this.paint = function (x, y) {
						context.fillStyle = "rgba(" + this.color[0] + "," + this.color[1] + "," + this.color[2] + "," + 1 + ")";
						//context.fillStyle = 'hsla(' + this.hue_final + ',100%,' + 70 + '%,' + 1 + ')'
						context.fillRect(x, y, 2, 2);
					}
				},
				dot2:function(x, y, img){
					this.dx = x;
					this.dy = y;
					this.img = img;
					this.paint = function (x, y) {
						context.drawImage(this.img, x, y)
					}
				},
				imgs: [],
				dots:[],
				dots2:[],
			}
		},
		mounted: function (e) {
			const that = this;
			const env = uni.getSystemInfoSync();
			this.width = env.screenWidth;
			//#ifdef MP-WEIXIN
				this.height = env.screenHeight - env.statusBarHeight - 44;
			//#endif
			// #ifdef MP-TOUTIAO
			this.height = env.screenHeight - env.statusBarHeight - 52;
			// #endif
			//#ifdef WEB || APP-PLUS
				this.height = env.screenHeight - env.statusBarHeight - 44;
			// #endif
			this.btn_choose_img.width = this.width * 2 / 3;
			this.btn_choose_img.height = 50;
			this.btn_choose_img.x = (this.width - this.btn_choose_img.width) / 2;
			this.btn_choose_img.y = that.height * 0.382;
			this.btn_choose_img.text_x = this.width / 2;
			// #ifdef MP-TOUTIAO
			this.btn_choose_img.text_x = this.width / 3;
			// #endif
			
			this.btn_choose_img.text_y = this.btn_choose_img.y + this.btn_choose_img.height / 2 + 2;
			// #ifdef MP-TOUTIAO
			this.btn_choose_img.text_y = this.btn_choose_img.y + this.btn_choose_img.height / 2 + 8;
			// #endif
			this.sq1.x = this.btn_choose_img.x + this.btn_choose_img.width / 2;
			this.sq1.y = this.btn_choose_img.y;
			this.ctx = uni.createCanvasContext('canvas', this);
			this.offctx = uni.createCanvasContext('offcanvas', this);
			context = this.ctx;
			this.offctx.textAlign = "center";
			this.offctx.textBaseline = "middle";
			this.offctx.fillStyle = "#ff0000"
			setTimeout(function(){
				that.draw_btn_choose_img()
			},500)
		},
		methods: {
			joke(){
				//自动还原
				for(var x in this.imgs){
					this.imgs[x].nowpos = this.imgs[x].opos;
					this.imgs[x].nowx = ((this.imgs[x].nowpos - 1) % this.ppline) * this.force_width + this.space * (this.imgs[x].nowpos - (Math.ceil(this.imgs[x].nowpos / this.ppline) - 1) * this.ppline );
					this.imgs[x].nowy = (Math.ceil(this.imgs[x].nowpos / this.ppline) - 1) * this.force_width + this.space * ((Math.ceil(this.imgs[x].nowpos / this.ppline)));
				}
				const that = this;
				that.drawCanvas()
			},
			draw_btn_choose_img(){
				this.steps = 0;
				this.ctx.rect(this.btn_choose_img.x, this.btn_choose_img.y, this.btn_choose_img.width, this.btn_choose_img.height);
				this.ctx.fillStyle = '#555555';
				this.ctx.fill();
				this.ctx.textAlign = "center";
				this.ctx.textBaseline = "middle";
				this.ctx.fillStyle = "#ff0000";
				this.ctx.font = "20px Arial";
				this.ctx.fillText(this.btn_choose_img.text, this.btn_choose_img.text_x, this.btn_choose_img.text_y);
				this.ctx.draw(true)
			},
			async initImage(){
				const that = this;
				if(this.img_width <= this.img_height){
					this.first_side = 1 //高图，优先选宽边
					this.ctx.drawImage(this.image, 0, 0,this.img_width, this.img_width, 0, 0, this.width, this.width);
				} else {
					this.first_side = 0 //宽图，优先选高边
					this.ctx.drawImage(this.image, 0, 0, this.img_height, this.img_height, 0, 0, this.width, this.width);
				}
				await this.ctx.draw(false, function(){
					uni.showLoading({
						title:'请稍候'
					});
					let i = 1;
					for(let i = 1; i <= that.ppline * that.ppline; i++){
						var space_line = (that.ppline + 1) * that.space;
						var force_width = Math.ceil((that.width - space_line) / that.ppline);
						that.force_width = force_width;
						var x_pos = ((i - 1) % that.ppline) * force_width + that.space * ( i - (Math.ceil(i / that.ppline) - 1) * that.ppline);
						var y_pos = ((Math.ceil(i / that.ppline) - 1) * force_width + that.space * ((Math.ceil(i / that.ppline))));
						that.imgs.push(new that.img_obj(i, i, null, x_pos, y_pos, that.force_width, that.force_width));
					}
					that.getImg(0);
				})
			},
			drawCanvas(){
				const that = this;
				for(var i = 0; i < this.imgs.length; i++){
					if(this.imgs[i].is_white == false){
						this.ctx.drawImage(this.imgs[i].img, 0, 0, this.imgs[i].width, this.imgs[i].height, this.imgs[i].nowx, this.imgs[i].nowy, this.imgs[i].width, this.imgs[i].height);
					} else {
						this.ctx.fillStyle = '#ffffff';
						this.ctx.fillRect(this.imgs[i].nowx, this.imgs[i].nowy, this.force_width, this.force_width);
					}
				}
				//画原图
				if(this.first_side == 1){	//高图
					this.ctx.drawImage(this.image, 0, 0, this.img_width, this.img_width, 0, this.height - this.width / 2, this.width / 2, this.width / 2);
				} else {
					this.ctx.drawImage(this.image, 0, 0, this.img_height, this.img_height, 0, this.height - this.width / 2, this.width / 2, this.width / 2);
				}
				this.ctx.font = "24px Arial";
				this.ctx.fillText(this.steps + '步', this.width - this.ctx.measureText(this.steps + '步').width, this.height - 50)
				
				if(that.win == false){
					let all_comp = true;
					let img_last;
					for(var i = 0; i < this.imgs.length; i++){
						if(this.imgs[i].is_white == true){
							img_last = this.imgs[i];
						}
						if(this.imgs[i].opos != this.imgs[i].nowpos){
							all_comp = false;
						}
					}
					if(all_comp == true){
						this.status = 3;
						img_last.is_white = false;
						that.ctx.drawImage(img_last.img, 0, 0, img_last.width,img_last.height, img_last.nowx, img_last.nowy, img_last.width, img_last.height);
						this.win = true;
						this.ctx.fillStyle = "rgba(0,0,0,0.7)";
						this.ctx.fillRect(0, 0, this.width, this.height);
						this.ctx.draw();
						setTimeout(function(){
							that.complete2();
						}, 1500)
					} else {
						this.ctx.draw();
					}
				} else {
					this.ctx.fillStyle = "rgba(0,0,0,0.7)";
					this.ctx.fillRect(0, 0, this.width, this.height);
					this.ctx.draw();
				}
			},
			complete2(){
				const that = this;
				for(var x in this.imgs){
					that.dots2.push(
						new that.dot2(this.imgs[x].nowx, this.imgs[x].nowy, this.imgs[x].img)
					);
				}
				for (var x in that.dots2) {
					that.dots2[x].x = Math.random() * that.width * 2;
					that.dots2[x].y = Math.random() * that.height * 2;
				}
				that.completed = 0;
				that.animate2();
			},
			complete(){
				const that = this;
				//var dots = [];
				let size = 100;
				this.offctx.font = size + 'px Avenir, Helvetica Neue, Helvetica, Arial, sans-serif';
				var test_width = this.offctx.measureText('拼图成功').width;
					this.offctx.fillStyle = "greenyellow";				
				while (test_width > this.width) {
					size -= 10;
					this.offctx.font = "bold " + size + "px Avenir, Helvetica Neue, Helvetica, Arial, sans-serif";
					test_width = this.offctx.measureText("拼图成功").width;
				}
				this.offctx.fillText("拼图成功", this.width / 2, this.height * 0.382);
				this.offctx.draw()
				// #ifdef MP-TOUTIAO
					setTimeout(function(){
						that.status = 0;
						that.dots = [];
						that.dots2 = [];
						that.imgs = [];
						that.win = false;
						that.ctx.draw();
						that.draw_btn_choose_img()
					}, 1500)
				// #endif
				// #ifndef MP-TOUTIAO
					uni.canvasGetImageData({
						canvasId:'offcanvas',
						x: 0,
						y: 0,
						width: that.width,
						height: that.height,
						success(imgData) {
							var step = 6;
							var half_step = step / 2;
							for (var x = 0; x < imgData.width; x += step) {
								for (var y = 0; y < imgData.height; y += step) {
									var i = (y * imgData.width + x) * 4;
									if (imgData.data[i] >= 128) {
										c1 = that.randomNum(50, 250);
										c2 = that.randomNum(150, 255);
										c3 = that.randomNum(100, 205);
										that.dots.push(
											new that.Dot(x - half_step, y - half_step, half_step / 2, [c1, c2, c3])
										);
									}
								}
							}
							for (var x in that.dots) {
								that.dots[x].x = Math.random() * that.width;
								that.dots[x].y = Math.random() * that.height;
							}
							that.completed = 0;
							that.animate();
						}
					},this)
				// #endif
				
			},
			animate2(){
				const that = this;
				this.drawCanvas();
				for (var x in this.dots2) {
					this.dots2[x].x += (this.dots2[x].dx - this.dots2[x].x) * 0.05;
					this.dots2[x].y += (this.dots2[x].dy - this.dots2[x].y) * 0.05;
					this.dots2[x].paint(this.dots2[x].x, this.dots2[x].y)
					if (Math.abs(this.dots2[x].x - this.dots2[x].dx) < 0.01 && Math.abs(this.dots2[x].y - this.dots2[x].dy) < 0.01) {
						this.completed += 1;
					}
				}
				this.ctx.draw(true);
				if(this.completed >= this.dots2.length){
					setTimeout(function(){
						console.log('complete');
						that.completed = 0;
						that.ctx.draw();
						that.complete();
					}, 1500)
					return;
				}
				setTimeout(function(){
					that.animate2();
				},20)
			},
			animate(){
				const that = this;
				//this.drawCanvas();
				const c = that.ctx;
				for (var x in this.dots) {
					this.dots[x].x += (this.dots[x].dx - this.dots[x].x) * 0.1;
					this.dots[x].y += (this.dots[x].dy - this.dots[x].y) * 0.1;
					//this.dots[x].paint(this.dots[x].x, this.dots[x].y)
					context.fillStyle = "rgba(" + this.dots[x].color[0] + "," + this.dots[x].color[1] + "," + this.dots[x].color[2] + "," + 1 + ")";
					//context.fillStyle = 'hsla(' + this.hue_final + ',100%,' + 70 + '%,' + 1 + ')'
					context.fillRect(this.dots[x].x, this.dots[x].y, 2, 2);
					if (Math.abs(this.dots[x].x - this.dots[x].dx) < 0.2 && Math.abs(this.dots[x].y - this.dots[x].dy) < 0.2) {
						this.completed += 1;
					}
				}
				this.ctx.draw();
				if(this.completed >= this.dots.length){
					console.log('complete' + this.dots.length);
					setTimeout(function(){
						that.status = 0;
						that.dots = [];
						that.dots2 = [];
						that.imgs = [];
						that.win = false;
						that.ctx.draw();
						that.draw_btn_choose_img()
					}, 1500)
					return;
				}
				setTimeout(function(){
					that.animate();
				},10)
			},
			getImg(i){
				const that = this;
				uni.canvasToTempFilePath({
					canvasId:'canvas',
					x: that.imgs[i].nowx,
					y :that.imgs[i].nowy,
				 	width: that.force_width,
				 	height: that.force_width,
					destWidth: that.force_width,
					destHeight: that.force_width,
					success: function(res) {
						that.imgs[i].img = res.tempFilePath;
						if(i < that.imgs.length - 1){
							that.getImg(++i)
						} else {
							var shuffle_result = that.shuffle(that.imgs);
							for(var x in shuffle_result){
								that.imgs[shuffle_result[x] - 1].nowpos = parseInt(x) + 1;
								that.imgs[shuffle_result[x] - 1].nowx = ((that.imgs[shuffle_result[x] - 1].nowpos - 1) % that.ppline) * that.force_width + that.space * (that.imgs[shuffle_result[x] - 1].nowpos - (Math.ceil(that.imgs[shuffle_result[x] - 1].nowpos / that.ppline) - 1) * that.ppline);
								that.imgs[shuffle_result[x] - 1].nowy = (Math.ceil(that.imgs[shuffle_result[x] - 1].nowpos / that.ppline) - 1) * that.force_width + that.space * ((Math.ceil(that.imgs[shuffle_result[x] - 1].nowpos / that.ppline)));
								if(x == shuffle_result.length - 1){
									that.imgs[shuffle_result[x] - 1].is_white = true;
									that.white_index = shuffle_result[x] - 1;
								}
							}
							that.status = 2;
							that.drawCanvas();
							uni.hideLoading();
						}
					},
					fail(e){
						uni.hideLoading()
						uni.showToast({
							title:'系统出现问题'
						})
					}
				}, that)
			},
			touchstart(res){
				const that = this;
				if(this.status == 0){
					if(res.changedTouches[0].x > this.btn_choose_img.x && res.changedTouches[0].x < this.btn_choose_img.x + this.btn_choose_img.width && res.changedTouches[0].y > this.btn_choose_img.y && res.changedTouches[0].y < this.btn_choose_img.y + this.btn_choose_img.height){
						uni.chooseImage({
							count: 1,
							mediaType:'image',
							sourceType:['album', 'camera'],
							success(res){
								let image = res.tempFiles[0]['path'];
								that.image = image;
								uni.showActionSheet({
									itemList:['3', '4', '5', '6', '7', '8'],
									title:'每行几张图片：',
									success(res){
										uni.getImageInfo({
											src:image,
											success: function(_image) {
												console.log(_image)
												that.img_width = _image.width;
												that.img_height = _image.height;
												that.status = 1;
												
												that.ppline = res.tapIndex + 3;
												that.initImage();
											}
										})
									}
									,fail(e){
										
									}
								})
							}
							,fail(e){
								console.log(e)
							}
						})
					}
				} else if(this.status == 2){
					var sourcex = res.touches[0].x;
					var sourcey = res.touches[0].y;
					var target_img = null;
					for(var x in this.imgs){
						if(this.imgs[x].nowx < sourcex && this.imgs[x].nowx + this.force_width > sourcex && this.imgs[x].nowy < sourcey && this.imgs[x].nowy + this.force_width > sourcey){
							target_img = x;
							break;
						}
					}
					if(this.imgs[target_img] != null && this.imgs[target_img].is_white == false){
						let x = this.white_index;
						if((this.imgs[x].nowpos - 1 == this.imgs[target_img].nowpos && this.imgs[target_img].nowpos % this.ppline != 0) || (this.imgs[x].nowpos + 1 == this.imgs[target_img].nowpos && this.imgs[x].nowpos % this.ppline != 0) || this.imgs[x].nowpos - this.ppline == this.imgs[target_img].nowpos || this.imgs[x].nowpos + this.ppline == this.imgs[target_img].nowpos){
							console.log('允许调换位置')
							this.steps += 1;
							var source_x = this.imgs[target_img].nowx;
							var source_y = this.imgs[target_img].nowy;
							var source_pos = this.imgs[target_img].nowpos;
							this.imgs[target_img].nowpos = this.imgs[x].nowpos;
							this.imgs[target_img].nowx = this.imgs[x].nowx;
							this.imgs[target_img].nowy = this.imgs[x].nowy;
							this.imgs[x].nowx = source_x;
							this.imgs[x].nowy = source_y;
							this.imgs[x].nowpos = source_pos;
							that.drawCanvas()
						}
					}
					
				}
			},
			shuffle(source){
				var $reverse_single = true;
				try{
					while($reverse_single == true){
						var num_list = [];
						var tmp_calc = [];
						var o_reverse_count = 0;
						var reverse_count = 0;
						var tmp = [];
					
						for(var i = 1; i <= source.length; i++){
							tmp.push(i);
							tmp_calc.push(i);
						}
						for(var i = 1; i <= tmp.length; i++){
							var rnd = this.randomNum(0, tmp.length - 1);
							num_list.push(tmp[rnd]);
							tmp.splice(rnd, 1);
							i -= 1;
						}
						for(var i = 0; i < tmp_calc.length; i++){
							if(tmp_calc[i] == num_list[num_list.length - 1]){
								tmp_calc[i] = 0;
							}
						}
						//原图逆序数.原图为tmp_calc
					
						var o_reverse_count = 0;
						var reverse_count = 0;
						for(var i = 0; i < tmp_calc.length - 1; i++){
							for(j = i + 1; j < tmp_calc.length; j++){
								if(tmp_calc[i] > tmp_calc[j]){
									o_reverse_count += 1;
								}
							}
						}
					
						var $num = num_list[num_list.length - 1];  //空白的那个数是哪块图片
						var $row = Math.ceil($num / this.ppline);
						var $mod = $num % this.ppline;
						var $col =  $mod == 0 ? this.ppline : $mod;
						var $o_is_single = (o_reverse_count + $row + $col) % 2 != 0 ? true : false;   //原矩阵  是否奇数
					
						
						//新图逆序数
						var new_pic = num_list;
					
						new_pic[new_pic.length - 1] = 0;
						for(var i = 0; i < new_pic.length - 1; i++){
							for(var j = i + 1; j < new_pic.length - 1; j++){
								if(new_pic[i] > new_pic[j]){
									reverse_count += 1;
								}
							}
						}
					
						var $row = this.ppline;
						var $col = this.ppline;
						var $reverse_single_new = (reverse_count + $row + $col) % 2 != 0 ? true :false;
					
						if(this.ppline % 2 == 0){
							if($o_is_single == $reverse_single_new){
								$reverse_single = true;
							} else {
								$reverse_single = false;
							}
						} else {
							if($o_is_single != $reverse_single_new){
								$reverse_single = true;
							} else {
								$reverse_single = false;
							}
						}
					}
					
					new_pic[new_pic.length - 1] = $num;
					console.log(new_pic)
					return new_pic;
				} catch(e) {
					alert(e)
				}
					
			},
			randomNum(min, max){
				switch (arguments.length) {
					case 1:
						return parseInt(Math.random() * min + 1, 10);
						break;
					case 2:
						return parseInt(Math.random() * (max - min + 1) + min, 10);
						break;
					default:
						return 0;
				}
			},
		}
	}
</script>
<style>
</style>
